home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 22
/
Cream of the Crop 22.iso
/
disk
/
cluster2.zip
/
SOURCE.ZIP
/
PB3BOXES.BU
< prev
next >
Wrap
Text File
|
1996-06-16
|
30KB
|
811 lines
'╒═══════════════════════════════════════════════════════════════════════════╕
'│ │
'│ Text Screen routines for PowerBASIC │
'│ Copyright (c) 1995 by PowerBASIC, Inc. All Rights Reserved. │
'│ │
'│ Note: These routines are written for maximum speed and will have to be │
'│ modified to prevent snow on older CGA cards. │
'│ │
'├───────────────────────────────────────────────────────────────────────────┤
'│ │
'│ LineEdit - Edit a line of text; can be longer than the edit window │
'│ LineInput - Get a line of text from the user with a specified limit │
'│ PgCopy - Copy one Text video page to another on a color screen │
'│ QATTR - Change the background attributes of a given location │
'│ QBOX - Display a text box with in a specified color │
'│ QFILL - Fill a specified location with a char and attribute │
'│ QPRINT - Quickly print a string to the screen │
'│ QPRINTC - Quickly print a centered string to the screen │
'│ QREST - Restore a saved portion of the screen │
'│ QSAVE - Save a portion of the screen │
'│ ScrollDown - Scroll a specified portion of the screen down │
'│ ScrollUp - Scroll a specified portion of the screen up │
'│ SetBlink - Change the blink bit status on EGA/VGA text screens │
'│ │
'├───────────────────────────────────────────────────────────────────────────┤
'│ │
'│ 10 June 96 -- Bud Durland │
'│ │
'│ Modified to store saved screen areas in dynamic strings; minor bug │
'│ in QATTR corrected; input routine changed for more control. │
'│ │
'│ The original routines in SCRNUNIT were written to save screen │
'│ areas inINTEGER arrays. This is OK if you are only doing one box at │
'│ a time, but is expensive in terms of memory for multiple boxes. │
'│ Using strings to save screen areas is more economical, since you can │
'│ create a string array for however many boxes you will be using, and │
'│ dynamic strings will then only consume enough memory to hold the │
'│ screen area specified. An integer array would always have to be │
'│ dimensioned for the largest possible screen area. │
'│ │
'╘═══════════════════════════════════════════════════════════════════════════╛
$COMPILE UNIT ".\SCRNUNIT.PBU"
$CODE SEG "SCRNLIB"
$CPU 8086 ' Make compatible with XT systems
$LIB ALL OFF ' Turn off all PowerBASIC libraries
$ERROR ALL OFF ' Turn off all PowerBASIC error checking
$OPTIMIZE SIZE ' Optimize for smaller code
DEFINT A-Z ' Required for all numeric functions, forces PB to not
' include floating point in UNIT (makes it smaller)
DECLARE SUB GetStrLoc() ' internal string locator in RTL
$INCLUDE ".\PB3BOXES.HDR" ' includes defs & declares for all modules.
'===========================================================================
' QSAVE - saves specified portion of a text screen in a string
'
' Row = Starting screen row of area to save
' Col = Starting screen column of area to save
' Rows = Number of rows to save (must be 1 or greater)
' Cols = Number of columns to save (must be 1 or greater)
' Where = string where data is to be saved
'
SUB QSAVE(BYVAL Row AS INTEGER, BYVAL Col AS INTEGER, _
BYVAL Rows AS INTEGER, BYVAL Cols AS INTEGER, _
Where AS STRING) LOCAL PUBLIC
DIM ScrnSeg AS INTEGER
DIM WhereMem AS DWORD
IF (pbvScrnCard AND 1) = 0 THEN
ScrnSeg = &HB800 ' color monitor
ELSE
ScrnSeg = &HB000 ' mono monitor
END IF
dLen% = (Rows * Cols) * 2 ' how much data to store?
Where = LEFT$(Where + SPACE$(dLen%),dLen%) ' make string long enough
WhereMem = STRPTR32(Where)
! push DS ; save DS for PowerBASIC
! les DI, WhereMem ; put location of array element in ES:DI
! mov AX, ScrnSeg ; put screen segment in AX
! mov DS, AX ; move to DS
! mov AX, Row ; put row in AX
! dec AX ; minus one
! mov CX, 160 ; AX =
! mul CX ; AX * 160
! mov SI, AX ; put it in SI
! mov AX, Col ; put column in AX
! dec AX ; minus one
! shl AX, 1 ; times 2
! add SI, AX ; add to SI
! mov DX, Rows ; put rows in DX
SaveRow:
! mov CX, Cols ; put number of columns in CX
! push SI ; save screen offset
! rep movsw ; copy CX words to array from screen
! pop SI ; restore screen offset
! add SI, 160 ; move to next row
! dec DX ; one less row to do
! jnz SaveRow ; if it's zero, we're done
! pop DS ; restore DS for PowerBASIC
END SUB
'===========================================================================
' QREST - Restores specified portion of a text screen from a string
'
' Row = Starting screen row of area to restore
' Col = Starting screen column of area to restore
' Rows = Number of rows to restore (must be 1 or greater)
' Cols = Number of columns to restore (must be 1 or greater)
' Where = Starting element of integer array where data is to be restored from
'
SUB QREST(BYVAL Row AS INTEGER, BYVAL Col AS INTEGER, _
BYVAL Rows AS INTEGER, BYVAL Cols AS INTEGER, _
Where AS STRING) LOCAL PUBLIC
DIM ScrnSeg AS INTEGER
DIM WhereMem AS DWORD
IF (pbvScrnCard AND 1) = 0 THEN
ScrnSeg = &HB800 ' color monitor
ELSE
ScrnSeg = &HB000 ' mono monitor
END IF
WhereMem = STRPTR32(Where) ' point to data in string
! push DS ; save DS for PowerBASIC
! lds SI, WhereMem ; put location of array in DS:SI
! mov AX, ScrnSeg ; put screen segment in AX
! mov ES, AX ; move to ES
! mov AX, Row ; put row in AX
! dec AX ; minus one
! mov CX, 160 ; AX =
! mul CX ; AX * 160
! mov DI, AX ; put it in DI
! mov AX, Col ; put column in AX
! dec AX ; minus one
! shl AX, 1 ; times 2
! add DI, AX ; add to DI
! mov DX, Rows ; put rows in DX
RestoreRow:
! mov CX, Cols ; put number of columns in CX
! push DI ; save screen offset
! rep movsw ; copy CX words to array from screen
! pop DI ; restore screen offset
! add DI, 160 ; move to next row
! dec DX ; one less row to do
! jnz RestoreRow ; if it's zero, we're done
! pop DS ; restore DS for PowerBASIC
END SUB
'===========================================================================
' QBOX - Display a box on the screen
'
' Row = Starting screen row of box
' Col = Starting screen column of box
' Rows = Number of rows for the box
' Cols = Number of columns for the box
' Attr = Color attribute of the box
'
SUB QBOX(BYVAL Row AS INTEGER, BYVAL Col AS INTEGER, _
BYVAL Rows AS INTEGER, BYVAL Cols AS INTEGER, _
BYVAL Attr AS INTEGER, BYVAL Bord AS INTEGER) PUBLIC
DIM ScrnSeg AS INTEGER
DIM TL.Char AS BYTE
DIM Vert AS BYTE
DIM TR.Char AS BYTE
DIM Horiz AS BYTE
DIM BL.Char AS BYTE
DIM BR.Char AS BYTE
IF (pbvScrnCard AND 1) = 0 THEN
ScrnSeg = &HB800 ' color monitor
ELSE
ScrnSeg = &HB000 ' mono monitor
END IF
Horiz? = ASC(MID$(BorderText$(Bord),1,1))
Vert? = ASC(MID$(BorderText$(Bord),2,1))
TL.Char? = ASC(MID$(BorderText$(Bord),3,1))
TR.Char? = ASC(MID$(BorderText$(Bord),4,1))
BL.Char? = ASC(MID$(BorderText$(Bord),5,1))
BR.Char? = ASC(MID$(BorderText$(Bord),6,1))
! push DS ; save DS for PowerBASIC
! mov AX, ScrnSeg ; put screen segment in AX
! mov ES, AX ; and in ES
! mov AX, Row ; put row in AX
! dec AX ; minus one
! mov CX, 160 ; AX =
! mul CX ; AX * 160
! mov DI, AX ; put it in DI
! mov AX, Col ; put column in AX
! dec AX ; minus one
! shl AX, 1 ; times 2
! add DI, AX ; add to DI
! mov DX, Rows ; put rows in DX
! dec DX ; minus top row
! dec DX ; minus bottom row
! mov CX, Cols ; put columns in CX
! dec CX ; minus left column
! dec CX ; minus right column
! mov AH, Attr ; put attribute in AH
! push CX ; save CX (columns)
! push DI ; and DI (screen location)
! mov AL, TL.Char? ; put top left char in AL
! stosw ; write it to the screen
! mov AL, Horiz? ; put top char in AL
! rep stosw ; write it to the screen CX times
! mov AL, TR.Char? ; put top right char in AL
! stosw ; write it to the screen
! pop DI ; restore DI
! pop CX ; and CX
HorizLoop:
! add DI, 160 ; move to next row on the screen
! push CX ; save CX
! push DI ; and DI
! mov AL, Vert? ; put left char in AL
! stosw ; write it to the screen
! mov AL, 32 ; put a space in AL
! rep stosw ; write it to the screen CX times
! mov AL, Vert? ; put right char in AL
! stosw ; write it to the screen
! pop DI ; restore DI
! pop CX ; and CX
! dec DX ; one less row
! jnz HorizLoop ; loop until DX (rows) = 0
! add DI, 160 ; move to next row on the screen
! mov AL, BL.Char? ; put bottom left char in AL
! stosw ; write it to the screen
! mov AL, Horiz? ; put bottom char in AL
! rep stosw ; write it to the screen CX times
! mov AL, BR.Char? ; put bottom right char in AL
! stosw ; write it to the screen
! pop DS ; restore DS for PowerBASIC
END SUB
'===========================================================================
' QFILL - fill area of the screen with specified character and attribute
'
' Row = Starting screen row of area to fill
' Col = Starting screen column of area to fill
' Rows = Number of rows to fill (must be 1 or greater)
' Cols = Number of columns to fill (must be 1 or greater)
' Char = ASCII character to fill block with
' Attr = Color attribute to fill block with
'
SUB QFILL(BYVAL Row AS INTEGER, BYVAL Col AS INTEGER, _
BYVAL Rows AS INTEGER, BYVAL Cols AS INTEGER, _
BYVAL Char AS INTEGER, BYVAL Attr AS INTEGER) PUBLIC
DIM ScrnSeg AS INTEGER
IF (pbvScrnCard AND 1) = 0 THEN
ScrnSeg = &HB800 ' color monitor
ELSE
ScrnSeg = &HB000 ' mono monitor
END IF
! push DS ; save DS for PowerBASIC
! mov AX, ScrnSeg ; put screen segment in AX
! mov ES, AX ; and in ES
! mov AX, Row ; put row in AX
! dec AX ; minus one
! mov CX, 160 ; AX =
! mul CX ; AX * 160
! mov DI, AX ; put it in DI
! mov AX, Col ; put column in AX
! dec AX ; minus one
! shl AX, 1 ; times 2
! add DI, AX ; add to DI
! mov DX, Rows ; put rows in DX
! mov AX, Char ; put character in AX
! mov AH, Byte Ptr Attr ; put attribute in AH
! mov CX, Cols ; put columns in CX
FillRow:
! push DI ; save DI
! push CX ; save CX
! rep stosw ; write CX words
! pop CX ; restore CX
! pop DI ; restore DI
! add DI, 160 ; move to next row
! dec DX ; one less row
! jnz FillRow ; loop until DX = 0
! pop DS ; restore DS for PowerBASIC
END SUB
'===========================================================================
' QATTR - fill area of the screen with specified attribute
'
' Row = Starting screen row of area to fill
' Col = Starting screen column of area to fill
' Rows = Number of rows to fill (must be 1 or greater)
' Cols = Number of columns to fill (must be 1 or greater)
' Attr = Color attribute to fill block with
'
SUB QATTR(BYVAL Row AS INTEGER, BYVAL Col AS INTEGER, _
BYVAL Rows AS INTEGER, BYVAL Cols AS INTEGER, _
BYVAL Attr AS INTEGER) PUBLIC
DIM ScrnSeg AS INTEGER
IF (pbvScrnCard AND 1) = 0 THEN
ScrnSeg = &HB800 ' color monitor
ELSE
ScrnSeg = &HB000 ' mono monitor
END IF
! push DS ; save DS for PowerBASIC
! mov AX, ScrnSeg ; put screen segment in AX
! mov ES, AX ; and in ES
! mov AX, Row ; put row in AX
! dec AX ; minus one
! mov CX, 160 ; AX =
! mul CX ; AX * 160
! mov DI, AX ; put it in DI
! mov AX, Col ; put column in AX
! dec AX ; minus one
! shl AX, 1 ; times 2
! add DI, AX ; add to DI
! mov DX, Rows ; put rows in DX
! mov AL, Byte Ptr Attr ; put attribute in AL
! mov CX, Cols ; put columns in CX
RecolorRow:
! push DI ; save DI
! push CX ; save CX
RecolorCol:
! inc DI ; skip character ' was after stosb -- bug
! stosb ; write attribute
! loop RecolorCol ; do it CX times
! pop CX ; restore CX
! pop DI ; restore DI
! add DI, 160 ; move to next row
! dec DX ; one less row
! jnz RecolorRow ; loop until DX = 0
! pop DS ; restore DS for PowerBASIC
END SUB
'===========================================================================
' QPRINT - print string to specified location on the screen in specified color
'
' Note: String is passed BYVAL to make it compatible with fixed length
' and flex strings. Since this uses the internal assembler, PB will
' automatically release the temporary string handle left on the stack.
' If it were an external assembler routine, it would be responsible for
' releasing the string.
'
' Row = Screen row to display text
' Col = Starting column to display text
' Text = Text string to display on screen
' Attr = Color attribute to display characters
'
SUB QPRINT(BYVAL Row AS INTEGER, BYVAL Col AS INTEGER, _
BYVAL Text AS STRING, BYVAL Attr AS INTEGER) PUBLIC
DIM ScrnSeg AS INTEGER
IF (pbvScrnCard AND 1) = 0 THEN
ScrnSeg = &HB800 ' color monitor
ELSE
ScrnSeg = &HB000 ' mono monitor
END IF
! push DS ; save DS for PowerBASIC
! push Word Ptr Text ; push string handle on the stack
! call GetStrLoc ; find the string
! jcxz QPExit ; if it's null, exit
! mov DS, DX ; put segment in DS
! mov SI, AX ; put offset in SI
! push CX ; save length
! mov AX, ScrnSeg ; put screen segment in AX
! mov ES, AX ; move to ES
! mov AX, Row ; put row in AX
! dec AX ; minus one
! mov CX, 160 ; AX =
! mul CX ; AX * 160
! mov DI, AX ; put it in DI
! mov AX, Col ; put column in AX
! dec AX ; minus one
! shl AX, 1 ; times 2
! add DI, AX ; add to DI
! pop CX ; restore length of string
! mov AH, Attr ; put attribute in AH
WriteChar:
! lodsb ; get char from string
! stosw ; write char and attribute to screen
! loop WriteChar ; do it all CX times
QPExit:
! pop DS ; restore DS for PowerBASIC
END SUB
'===========================================================================
' QPRINTC - Print a string centered between two columns on the specified
' row.
'
' Row = Screen row to display text
' ColL = Starting column to center displayed text
' ColR = Ending column to center displayed text
' Text$ = Text string to display on screen
' Attr = Color attribute to display characters
'
SUB QPRINTC(BYVAL Row AS INTEGER, BYVAL ColL AS INTEGER, _
BYVAL ColR AS INTEGER, BYVAL Text AS STRING, _
BYVAL Attr AS INTEGER)
DIM Temp AS INTEGER
Temp = (ColL + ((ColR - ColL) \ 2)) - (LEN(Text$) \ 2)
QPRINT Row, Temp, Text$, Attr
END SUB
'===========================================================================
' SetBlink - Change the status of the blink bit on EGA/VGA color monitors.
'
' Status - A zero indicates a normal blink bit. A non-zero indicates
' the blink bit is a high-intensity background.
'
SUB SetBlink(BYVAL Status AS INTEGER)
IF BIT(pbvScrnCard, 4) THEN ' only works on EGA/VGA monitors
Status = (Status <> 0) AND 1 ' convert to 0 or 1
! mov AX, &H1003
! mov BX, Status
! int &H10
END IF
END SUB
'===========================================================================
' PgCopy - Copy data from one text page to another
'
' SourcePage = Text page to copy from (starts with 0)
' TargetPage = Text page to copy to (starts with 0)
'
SUB PgCopy(BYVAL SourcePage AS INTEGER, BYVAL TargetPage AS INTEGER) PUBLIC
DIM PageSize AS INTEGER
DIM ScrnSeg AS INTEGER
IF (pbvScrnCard AND 1) = 1 THEN ' monochrome adaptor only has 1 page
EXIT SUB
END IF
IF (pbvScrnRows = 25) AND (pbvScrnCols = 80) THEN
PageSize = 4096 ' 80x25 = 4k page; could be buggy CGA
ELSEIF (pbvScrnRows = 25) AND (pbvScrnCols = 40) THEN
PageSize = 2048 ' 40x25 = 2k page; could be buggy CGA
ELSE
! push DS ; save DS for PowerBASIC
! xor AX, AX ; clear AX
! mov DS, AX ; and DS
! mov AX, DS:[&H044C] ; get page size from BIOS
! mov PageSize, AX ; put it in PageSize
! pop DS ; restore DS for PowerBASIC
END IF
SourcePage = SourcePage * PageSize ' calculate offset of source page
TargetPage = TargetPage * PageSize ' calculate offset of target page
ScrnSeg = &HB800 ' only color adaptors have multiple pages
! push DS ; save DS for PowerBASIC
! mov AX, ScrnSeg ; put screen segment in AX
! mov ES, AX ; and in ES
! mov DS, AX ; and in DS
! mov SI, SourcePage ; put source page offset in SI
! mov DI, TargetPage ; put target page offset in DI
! mov CX, PageSize ; put page size in CX
! shr CX, 1 ; divide by two
! rep movsw ; move data as words (faster than bytes)
! pop DS ; restore DS for PowerBASIC
END SUB
'===========================================================================
' ScrollUp - Scroll the specified part of the screen up
'
' Row = Starting row on screen of scroll area
' Col = Starting column on screen of scroll area
' Rows = Total rows on screen of scroll area
' Cols = Total cols on screen of scroll area
' Attr = Color attribute for new blank lines
' HowMany = How many lines to scroll in specified area
'
SUB ScrollUp(BYVAL Row AS INTEGER, BYVAL Col AS INTEGER, _
BYVAL Rows AS INTEGER, BYVAL Cols AS INTEGER, _
BYVAL Attr AS INTEGER, BYVAL HowMany AS INTEGER)
DECR Row ' convert Row to 0 base
DECR Col ' convert Col to 0 base
INCR Rows, Row - 1 ' convert Rows to bottom row coordinate
INCR Cols, Col - 1 ' convert Cols to right col coordinate
! push DS ; save DS for PowerBASIC
! mov AH, 6 ; AH = service 6, scroll up
! mov AL, HowMany ; AL = number of lines to scroll
! mov BH, Byte Ptr Attr ; BH = color of new text line
! mov BL, DS:pbvScrnAPage ; BL = active display page
! mov CH, Row ; CH = starting row
! mov CL, Col ; CL = starting column
! mov DH, Rows ; DH = ending row
! mov DL, Cols ; DL = ending column
! int &H10 ; call Video BIOS
! pop DS ; restore DS for PowerBASIC
END SUB
'===========================================================================
' ScrollDown - Scroll the specified part of the screen down
'
' Row = Starting row on screen of scroll area
' Col = Starting column on screen of scroll area
' Rows = Total rows on screen of scroll area
' Cols = Total cols on screen of scroll area
' Attr = Color attribute for new blank lines
' HowMany = How many lines to scroll in specified area
'
SUB ScrollDown(BYVAL Row AS INTEGER, BYVAL Col AS INTEGER, _
BYVAL Rows AS INTEGER, BYVAL Cols AS INTEGER, _
BYVAL Attr AS INTEGER, BYVAL HowMany AS INTEGER)
DECR Row ' convert Row to 0 base
DECR Col ' convert Col to 0 base
INCR Rows, Row - 1 ' convert Rows to bottom row coordinate
INCR Cols, Col - 1 ' convert Cols to right col coordinate
! push DS ; save DS for PowerBASIC
! mov AH, 7 ; AH = service 6, scroll down
! mov AL, HowMany ; AL = number of lines to scroll
! mov BH, Byte Ptr Attr ; BH = color of new text line
! mov BL, DS:pbvScrnAPage ; BL = active display page
! mov CH, Row ; CH = starting row
! mov CL, Col ; CL = starting column
! mov DH, Rows ; DH = ending row
! mov DL, Cols ; DL = ending column
! int &H10 ; call Video BIOS
! pop DS ; restore DS for PowerBASIC
END SUB
'===========================================================================
' LineEdit - Allow the end user to edit a text line
'
' Row = Row to display edit field
' Col = Column to display edit field
' Text$ = Text string to edit
' Attr = Color attribute to display string
' EdLen = Length of edit window
' MaxLen = Maximum edit length
''
' Mods for Library routine -- bud
' GoodKeys$ = Keys that can be accepted for input. Good if you want
' numerics only, etc. Case insensitive.
' TermKeys$ = What keys will exit this routine; If this is blank,
' Enter and Esc are used.
' ExitKey% = tells what key exited this routine. For two-byte exit keys,
' (pgUp, DownArrow, etc), this is set to 255 + the ASC of the
' second byte.
'
SUB LineEdit(BYVAL Row AS INTEGER, BYVAL Col AS INTEGER, _
Text AS STRING, BYVAL Attr AS INTEGER, _
BYVAL GoodKeys AS STRING, BYVAL TermKeys AS STRING, _
ExitKey AS INTEGER, BYVAL EdLen AS INTEGER, _
BYVAL MaxLen AS INTEGER) PUBLIC
DIM Ins AS INTEGER
DIM Cursor AS INTEGER
DIM OldCurX AS INTEGER
DIM OldCurY AS INTEGER
DIM OldCurTop AS INTEGER
DIM Begin AS INTEGER
DIM I AS STRING
DIM Temp AS STRING
IF EdLen > MaxLen THEN
MaxLen = EdLen
END IF
Ins = 0
Cursor = 1
Begin = 1
OldCurX = POS
OldCurY = CSRLIN
OldCurTop = pbvCursor1
Temp$ = Text$ + SPACE$( MaxLen-LEN(Text$) )
LOCATE Row, Col+Cursor-1, 1
DO
QPRINT Row, Col, MID$(Temp$, Begin, EdLen), Attr
LOCATE Row, Col + Cursor - 1
DO
I$ = INKEY$
LOOP WHILE LEN(I$) = 0
SELECT CASE I$
CASE CHR$(27) 'Esc
EXIT DO
CASE CHR$(13) 'Return
EXIT DO
CASE CHR$(0, 82) 'Insert
IF Ins = 0 THEN
Ins = -1
LOCATE , , 1, pbvCursor1 - 2, pbvCursor2
ELSE
Ins = 0
LOCATE , , 1, pbvCursor1 + 2, pbvCursor2
END IF
CASE CHR$(0, 75) 'Left arrow
IF (Begin + Cursor - 1) > 1 THEN
DECR Cursor
IF Cursor = 0 THEN
Cursor = 1
DECR Begin
END IF
END IF
CASE CHR$(0, 77) 'Right arrow
IF (Begin + Cursor - 1) <= LEN(Temp$) THEN
INCR Cursor
IF Cursor > EdLen THEN
Cursor = EdLen
INCR Begin
END IF
END IF
CASE CHR$(8) 'Backspace
IF (Begin + Cursor - 1) > LEN(Temp$) THEN
Temp$ = LEFT$(Temp$, LEN(Temp$) - 1) + " "
DECR Cursor
ELSEIF (Begin + Cursor - 1) > 1 THEN
Temp$ = LEFT$(Temp$, Begin + Cursor - 3) _
+ MID$(Temp$, Begin + Cursor - 1) + " "
DECR Cursor
END IF
IF Cursor = 0 THEN
Cursor = 1
DECR Begin
END IF
CASE CHR$(0, 79) 'End
Cursor = LEN(RTRIM$(Temp$))+1
IF Cursor > EdLen THEN
Begin = Cursor - EdLen + 1
Cursor = EdLen
END IF
CASE CHR$(0, 71) 'Home
Cursor = 1
Begin = 1
CASE ELSE
IF INSTR(TermKeys, I$) > 0 THEN ' a termination key
EXIT DO
END IF
IF (LEN(GoodKeys) > 0) AND (INSTR(GoodKeys,UCASE$(I$)) = 0) THEN
ITERATE DO ' this key not allowed
END IF
IF (Begin + Cursor - 1) <= LEN(Temp$) THEN
IF ASCII(I$) > 31 THEN
IF Ins = 0 THEN
MID$(Temp$, Begin + Cursor - 1, 1) = I$
INCR Cursor
ELSE
IF RIGHT$(Temp$, 1) = " " THEN
Temp$ = LEFT$(Temp$, Begin+Cursor-2) _
+ I$ _
+ MID$(Temp$, Begin+Cursor-1, LEN(Temp$)-(Begin+Cursor-1))
INCR Cursor
END IF
END IF
END IF
IF Cursor > EdLen THEN
Cursor = EdLen
INCR Begin
END IF
END IF
END SELECT
LOOP
ExitKey% = ASC(I$)
IF LEN(I$) = 2 THEN ExitKey% = 255 + ASC(MID$(I$,2))
LOCATE OldCurY, OldCurX, 0, OldCurTop, pbvCursor2
Text = RTRIM$(Temp)
END SUB
'===========================================================================
' LineInput - Allow the end user to input a text line with a specified
' maximum length. Uses the FLEXCHR$ value to show the maximum
' field length.
'
' Default$ = Default for input data
' MaxLength = Maximum length of input data
'
SUB LineInput(Default AS STRING, BYVAL MaxLength AS INTEGER) PUBLIC
DIM Row AS INTEGER
DIM Col AS INTEGER
DIM CharCount AS INTEGER
DIM C AS STRING
Row = CSRLIN 'use the current cursor position
Col = POS ' to mimic LINE INPUT.
CharCount = LEN(Default$)
DO
LOCATE Row, Col, 0
PRINT STRING$(MaxLength, FLEXCHR$); ' show the size of the field
LOCATE Row, Col, 1 ' be sure to turn the cursor on
PRINT Default$;
DO
C$ = INKEY$
LOOP UNTIL LEN(C$)
SELECT CASE C$
CASE CHR$(8) 'backspace
IF CharCount > 0 THEN 'If more than zero characters, delete one
DECR CharCount
Default$ = LEFT$( Default$, LEN( Default$ ) - 1 )
LOCATE Row, Col, 0 'turn the cursor off
PRINT Default$;FLEXCHR$; 'erase the deleted char from the screen
END IF
CASE CHR$(13) 'Return was pressed so end loop
EXIT LOOP
CASE ELSE
IF (ASCII(C$)>31) AND (LEN(Default$)<MaxLength) THEN
Default$ = Default$ + C$ 'Add the new character to the string
INCR CharCount
END IF
END SELECT
LOOP
LOCATE ,,0 'turn off the cursor
PRINT 'and move to the next line
END SUB